package net.wanglu.www.zzz.rule.pronoun;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Pattern;

import net.wanglu.www.zzz.rule.Rule;

import org.apache.commons.collections.MapUtils;

public abstract class _PronounRule extends Rule {

    public enum Person {
        First, Senond, Third;    
    }

	public static final int AnimacyANIMATECode = 1;
	public static final int AnimacyINANIMATECode = 1 << 1;
	public static final int AnimacyUNKNOWNCode = AnimacyANIMATECode | AnimacyINANIMATECode;
	
	public static final int GenderFEMALECode = 1 << 3;
	public static final int GenderMALECode = 1 << 4;
	public static final int GenderNEUTRALCode = 1 << 5;
	public static final int GenderUNKNOWNCode = GenderFEMALECode | GenderMALECode | GenderNEUTRALCode;
	
	public static final int NumberPLURALCode = 1 << 7;
	public static final int NumberSINGULARCode = 1 << 8;
	public static final int NumberUNKNOWNCode = NumberPLURALCode | NumberSINGULARCode;
	
	public static final int FirstPersonCode = 1 << 10;
	public static final int SecondPersonCode = 1 << 11;
	public static final int ThirdPersonCode = 1 << 12;
	public static final int PersonUNKNOWNCode = FirstPersonCode | SecondPersonCode | ThirdPersonCode;
	
	public static final int NominativeCode = 1 << 13;
	public static final int ObjectiveCode = 1 << 14;
	public static final int PossessiveAdjCode = 1 << 15;
	public static final int PossessiveNounCode = 1 << 16;
	public static final int NomCaseAndObjCaseUNKNOWNCode = NominativeCode | ObjectiveCode;
	public static final int AdjPossCaseAndNounPossCaseUNKNOWNCode = PossessiveAdjCode | PossessiveNounCode;
	public static final int ObjCaseAndAdjPossCaseUNKNOWNCode = PossessiveAdjCode | ObjectiveCode;
	
	public static final int RestrictiveCode = 1 << 17;
	public static final int NonRestrictiveCode = 1 << 18;
	public static final int RestrictiveUNKNOWNCode = RestrictiveCode | NonRestrictiveCode;
	
	public static HashMap<String, Integer> PronounMapInt = new HashMap<String, Integer>(64);
	public static HashMap<Integer, String> IntMapPronoun = null;
	static {
		PronounMapInt.put("I", AnimacyANIMATECode|GenderUNKNOWNCode|NumberSINGULARCode|FirstPersonCode|NominativeCode);
		PronounMapInt.put("me", AnimacyANIMATECode|GenderUNKNOWNCode|NumberSINGULARCode|FirstPersonCode|ObjectiveCode);
		PronounMapInt.put("my", AnimacyANIMATECode|GenderUNKNOWNCode|NumberSINGULARCode|FirstPersonCode|PossessiveAdjCode);
		PronounMapInt.put("mine", AnimacyANIMATECode|GenderUNKNOWNCode|NumberSINGULARCode|FirstPersonCode|PossessiveNounCode);

		PronounMapInt.put("you", AnimacyANIMATECode|GenderUNKNOWNCode|NumberUNKNOWNCode|SecondPersonCode|NomCaseAndObjCaseUNKNOWNCode);
		PronounMapInt.put("your", AnimacyANIMATECode|GenderUNKNOWNCode|NumberUNKNOWNCode|SecondPersonCode|PossessiveAdjCode);
		PronounMapInt.put("yours", AnimacyANIMATECode|GenderUNKNOWNCode|NumberUNKNOWNCode|SecondPersonCode|PossessiveNounCode);

		PronounMapInt.put("he", AnimacyANIMATECode|GenderMALECode|NumberSINGULARCode|ThirdPersonCode|NominativeCode);
		PronounMapInt.put("him", AnimacyANIMATECode|GenderMALECode|NumberSINGULARCode|ThirdPersonCode|ObjectiveCode);
		PronounMapInt.put("his", AnimacyANIMATECode|GenderMALECode|NumberSINGULARCode|ThirdPersonCode|AdjPossCaseAndNounPossCaseUNKNOWNCode);

		PronounMapInt.put("she", AnimacyANIMATECode|GenderFEMALECode|NumberSINGULARCode|ThirdPersonCode|NominativeCode);
		PronounMapInt.put("her", AnimacyANIMATECode|GenderFEMALECode|NumberSINGULARCode|ThirdPersonCode|ObjectiveCode);
		PronounMapInt.put("hers", AnimacyANIMATECode|GenderFEMALECode|NumberSINGULARCode|ThirdPersonCode|ObjCaseAndAdjPossCaseUNKNOWNCode);

		PronounMapInt.put("it", AnimacyINANIMATECode|GenderNEUTRALCode|NumberSINGULARCode|ThirdPersonCode|NomCaseAndObjCaseUNKNOWNCode);
		PronounMapInt.put("its", AnimacyINANIMATECode|GenderNEUTRALCode|NumberSINGULARCode|ThirdPersonCode|AdjPossCaseAndNounPossCaseUNKNOWNCode);

		PronounMapInt.put("we", AnimacyANIMATECode|GenderUNKNOWNCode|NumberPLURALCode|FirstPersonCode|NominativeCode);
		PronounMapInt.put("us", AnimacyANIMATECode|GenderUNKNOWNCode|NumberPLURALCode|FirstPersonCode|ObjectiveCode);
		PronounMapInt.put("our", AnimacyANIMATECode|GenderUNKNOWNCode|NumberPLURALCode|FirstPersonCode|PossessiveAdjCode);
		PronounMapInt.put("ours", AnimacyANIMATECode|GenderUNKNOWNCode|NumberPLURALCode|FirstPersonCode|PossessiveNounCode);

		PronounMapInt.put("they", AnimacyANIMATECode|GenderUNKNOWNCode|NumberPLURALCode|ThirdPersonCode|NominativeCode);
		PronounMapInt.put("them", AnimacyANIMATECode|GenderUNKNOWNCode|NumberPLURALCode|ThirdPersonCode|ObjectiveCode);
		PronounMapInt.put("their", AnimacyANIMATECode|GenderUNKNOWNCode|NumberPLURALCode|ThirdPersonCode|PossessiveAdjCode);
		PronounMapInt.put("theirs", AnimacyANIMATECode|GenderUNKNOWNCode|NumberPLURALCode|ThirdPersonCode|PossessiveNounCode);
		
		PronounMapInt.put("that", AnimacyUNKNOWNCode|GenderUNKNOWNCode|NumberUNKNOWNCode|PersonUNKNOWNCode|NomCaseAndObjCaseUNKNOWNCode|RestrictiveUNKNOWNCode);
		PronounMapInt.put("who", AnimacyANIMATECode|GenderUNKNOWNCode|NumberUNKNOWNCode|PersonUNKNOWNCode|NominativeCode|RestrictiveCode);
		PronounMapInt.put("whom", AnimacyANIMATECode|GenderUNKNOWNCode|NumberUNKNOWNCode|PersonUNKNOWNCode|ObjectiveCode|RestrictiveCode);
		PronounMapInt.put("which", AnimacyINANIMATECode|GenderNEUTRALCode|NumberUNKNOWNCode|PersonUNKNOWNCode|NomCaseAndObjCaseUNKNOWNCode|RestrictiveUNKNOWNCode);
		PronounMapInt.put("whose", AnimacyUNKNOWNCode|GenderUNKNOWNCode|NumberUNKNOWNCode|PersonUNKNOWNCode|PossessiveAdjCode|RestrictiveUNKNOWNCode);
		IntMapPronoun = (HashMap<Integer, String>) MapUtils.invertMap(PronounMapInt);
	}
	
	public static Pattern PronounTag = Pattern.compile("\\bPRP\\b|\\bPRP\\$\\b|\\bWP\\b|\\bWP$\\b");
	/*
	 * 代词主格,宾格,所有格,形容词性所有格
	 */
	public static Pattern PronounsNominative = Pattern.compile("\\bI\\b|\\b[Yy]ou\\b|\\b[Hh]e\\b|\\b[Ss]he\\b|\\b[Ii]t\\b|\\b[Ww]e\\b|\\b[Tt]hey\\b|\\b[Ww]ho\\b");
	public static Pattern PronounsObjective = Pattern.compile("\\bme\\b|\\byou\\b|\\bhim\\b|\\bher\\b|\\bit\\b|\\bus\\b|\\bthem\\b|\\b[Ww]hom\\b");
	public static Pattern PronounsPossessiveAdj = Pattern.compile("\\b[Mm]y\\b|\\b[Yy]our\\b|\\b[Hh]is\\b|\\b[Hh]er\\b|\\b[Ii]ts\\b|\\b[Oo]ur\\b|\\b[Tt]heir\\b|\\b[Ww]hose\\b");
	public static Pattern PronounsPossessiveNoun = Pattern.compile("\\b[Mm]ine\\b|\\b[Yy]ours\\b|\\b[Hh]is\\b|\\b[Hh]ers\\b|\\b[Ii]ts\\b|\\b[Oo]urs\\b|\\b[Tt]heirs\\b");
	/*
	 * 代词第一人称,第二人称,第三人称
	 */
	public static Pattern FirstPerson = Pattern.compile("\\bI\\b|\\bme\\b|\\bmy\\b|\\bmine\\b|\\bwe\\b|\\bus\\b|\\bour\\b|\\bours\\b", Pattern.CASE_INSENSITIVE);
	public static Pattern SecondPerson = Pattern.compile("\\byou\\b|\\byour\\b|\\byours\\b", Pattern.CASE_INSENSITIVE);
	public static Pattern ThirdPerson = Pattern.compile("\\bhe\\b|\\bshe\\b|\\bit\\b|\\bhim\\b|\\bher\\b|\\bhis\\b|\\bhers\\b|\\bits\\b|\\bthey\\b|\\bthem\\b|\\btheir\\b|\\btheirs\\b");

	@Override
	public Object applicable(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		HashMap<?, ?> preprocessData = (HashMap<?, ?>) objects[0];
		ArrayList<?> tags = (ArrayList<?>) preprocessData.get("tags");
		
		for( int i=0; i<tags.size(); i++) {
			if ( PronounTag.matcher((CharSequence) tags.get(i)).find()) {
				return Rule.Applicable;
			}
		}
		return Rule.Inapplicable;
	}

	@Override
	public Object deviseRightSolution(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}
	
	@Override
	public Object examine(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object whyItsWrong(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}
}
